package com.example.generator.impl;

import com.example.exception.GeneratorException;
import com.example.generator.Generator;
import com.example.model.DbConfig;
import com.example.model.Model;
import com.example.model.PathConfig;
import com.example.model.ProjectConfig;
import com.example.util.CodeUtil;
import com.example.util.ConfigUtil;
import com.example.util.DataBaseUtil;
import com.example.code.CoreCode;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PartGenerator implements Generator {
    @Override
    public void makeCode(Model model, String author, ProjectConfig projectConfig, DbConfig dbConfig, String fileName, String type, String filterName) {
        File file = new File(fileName);
        if (!file.exists()){
            file.mkdirs();
        }
        //生成 dao entity
        getEntity(model, author, projectConfig,dbConfig, fileName,type,filterName);
        getDaoAndMapper(model, author,dbConfig, projectConfig, fileName, type,filterName);
        //service facade
        CoreCode.getService(model, author, projectConfig, fileName, type,filterName);
        CoreCode.getFacade(model, author, projectConfig, fileName, type,filterName);
    }
    /**
     * Description: 生存dao或Mapper
     * @author: 王培喜(58528792@163.com)
     * @date:  2021/8/25 15:07
     */
    private void getDaoAndMapper(Model model, String author, DbConfig dbConfig, ProjectConfig projectConfig, String fileName, String type, String filterName) {
        try {
            dbConfig.setTableName(model.getTableName());
            List<Map<String, Object>> tableDetails = getTableDetails(dbConfig);
            Map<String, Object> data = CodeUtil.setParam(model, author,projectConfig);
            data.put("dataList",tableDetails);
            data.put("tableName",model.getTableName());
            Map autoIncrement = DataBaseUtil.getAutoIncrement(dbConfig, model.getTableName());
            if(null != autoIncrement){
                data.put("autoIncrement",autoIncrement.get("autoIncrement"));
                data.put("resutId",autoIncrement.get("resutId"));
            }

            String domainNameLowerCamel = data.get("domainNameLowerCamel").toString();
            String domainNameUpperCamel = data.get("domainNameUpperCamel").toString();
            //过滤表前缀
            filterName = ConfigUtil.filterTableName(model.getTableName(), filterName);
            if(null != filterName){
                domainNameLowerCamel = ConfigUtil.camelCaseName(model.getTableName().replace(filterName,""));
                domainNameUpperCamel = domainNameLowerCamel.substring(0,1).toUpperCase()+ domainNameLowerCamel.substring(1);

            }
            data.put("domainNameLowerCamel",domainNameLowerCamel );
            data.put("domainNameUpperCamel",domainNameUpperCamel );
            data.put("entity","Entity");
            String savePath, savePath1, tempName, tempName1;

            savePath = fileName + PathConfig.mapper;
            savePath1 = fileName + PathConfig.mapper;
            data.put("interfaceType","Mapper");
            data.put("interface","mapper");
            //持久类型
            if(!type.isEmpty() && type.equalsIgnoreCase("dao")){
                savePath = fileName + PathConfig.dao;
                savePath1 = fileName + PathConfig.dao;
                data.put("interfaceType",type);
                data.put("interface",type.toLowerCase());
            }else{
                type = "Mapper";
            }
             savePath =  savePath + data.get("domainNameUpperCamel") + type + ".java";
             tempName = "code/IDaoMarker.ftl";
            savePath1 = savePath1 + "xml/" + data.get("domainNameUpperCamel")  + type + ".xml";
            tempName1 = "code/MapperXMLMarker.ftl";
            CodeUtil.tempFactory(savePath, tempName, data);
            System.out.println(data.get("domainNameUpperCamel") + type + ".java 生成成功");
            CodeUtil.tempFactory(savePath1, tempName1, data);
            System.out.println(data.get("domainNameUpperCamel")  + type + ".xml 生成成功");

        }catch (Exception e){
            e.printStackTrace();
            throw new GeneratorException("生成Mapper失败");
        }
    }

    /**
     * Description: 生存entity
     * @author: 王培喜(58528792@163.com)
     * @date:  2021/8/25 15:07
     */
    public void getEntity(Model model, String author, ProjectConfig projectConfig, DbConfig dbConfig, String fileName, String type, String filterName){

        try{
            dbConfig.setTableName(model.getTableName());
            List<Map<String, Object>> tableDetails = getTableDetails(dbConfig);
            Map<String, Object> data = CodeUtil.setParam(model, author,projectConfig);
            String domainNameLowerCamel = data.get("domainNameLowerCamel").toString();
            String domainNameUpperCamel = data.get("domainNameUpperCamel").toString();
            //过滤表前缀
            filterName = ConfigUtil.filterTableName(model.getTableName(), filterName);
            if(null != filterName){
                domainNameLowerCamel = ConfigUtil.camelCaseName(model.getTableName().replace(filterName,""));
                domainNameUpperCamel = domainNameLowerCamel.substring(0,1).toUpperCase()+ domainNameLowerCamel.substring(1);
            }
            data.put("domainNameLowerCamel",domainNameLowerCamel + "Entity");
            data.put("domainNameUpperCamel",domainNameUpperCamel + "Entity");
            data.put("dataList",tableDetails);
            data = implCheck(data,dbConfig);
            String savePath = fileName + PathConfig.entity + data.get("domainNameUpperCamel") + ".java";
            String tempName = "code/EntityMarker.ftl";
            CodeUtil.tempFactory(savePath, tempName, data);
            System.out.println(data.get("domainNameUpperCamel") + ".java 生成成功");
        } catch (Exception e) {
            throw new GeneratorException("生成Entity失败" + model.getTableName());
        }
    }
    /**
      * 校验需要注入的类
      * @Author 王培喜 58528792@163.com
      * @Date 2021/12/1 17:48
     */
    private Map<String, Object> implCheck(Map<String, Object> data, DbConfig dbConfig) {
        List<String> columnComments = DataBaseUtil.getColumnComments(dbConfig);
        List<String> columnTypes = DataBaseUtil.getColumnTypes(dbConfig);
        for (int i = 0; i < columnComments.size(); i++) {
            String s = ConfigUtil.switchObjectByOracle(columnTypes.get(i));
            if(s.equalsIgnoreCase("date")){
                data.put("shijian",true);
            }
            if(s.equalsIgnoreCase("bigdecimal")){
                data.put("big",true);
            }
        }
        return data;
    }
    /**
     * Description: 获取表信息
     * @author: 王培喜(58528792@163.com)
     * @date:  2021/8/25 15:11
     * @return
     */
    public List<Map<String, Object>> getTableDetails(DbConfig dbConfig){
        HashMap<String, List<String>> map = new HashMap<>(16);
        List<String> columnNames = DataBaseUtil.getColumnNames(dbConfig);
        List<String> columnTypes = DataBaseUtil.getColumnTypes(dbConfig);
        List<String> columnComments = DataBaseUtil.getColumnComments(dbConfig);
        map.put("columnNames", columnNames);
        map.put("columnTypes", columnTypes);
        map.put("ColumnComments", columnComments);
        List<Map<String, Object>> list = new ArrayList<>();
        for (int i = 0; i < columnComments.size(); i++) {
            Map<String,Object> m = new HashMap<>();
            //数据类型转java类型
            m.put("jdbcType",columnTypes.get(i));
            m.put("dataType",ConfigUtil.switchObjectByOracle(columnTypes.get(i)));
            m.put("newColumn", ConfigUtil.camelCaseName(columnNames.get(i)));
            m.put("columnName",columnNames.get(i));
            m.put("comment",columnComments.get(i));
            list.add(m);
        }

        return list;
    }



}
